import java.util.Random;
import java.util.Arrays;

/**
 * 加减法口算练习系统 V0.3
 * 支持无重复算式生成，确保加法和减法都有出现
 */
public class CalculationSystemV03 {
    private static final int EQUATION_NUMBER = 50; // 题目数量
    private static final int COLUMN_NUMBER = 5;   // 每行显示的题目数量
    private static Random random = new Random();
    
    /**
     * Equation类：表示一个算式，包含操作数、运算符和结果
     */
    static class Equation {
        int leftOperand;   // 左操作数
        int rightOperand;  // 右操作数
        char operator;     // 运算符
        int result;        // 结果
        
        // 构造函数
        public Equation(int left, int right, char op) {
            this.leftOperand = left;
            this.rightOperand = right;
            this.operator = op;
            calculateResult();
        }
        
        // 计算结果
        private void calculateResult() {
            if (operator == '+') {
                this.result = leftOperand + rightOperand;
            } else if (operator == '-') {
                this.result = leftOperand - rightOperand;
            }
        }
        
        // 重写toString方法，用于格式化输出
        @Override
        public String toString() {
            return String.format("%2d%c%2d=%3d", leftOperand, operator, rightOperand, result);
        }
    }
    
    /**
     * 主函数
     */
    public static void main(String[] args) {
        // 输出系统标题
        System.out.println("加减法口算练习系统-v0.3");
        System.out.println("====================================");
        
        // 创建题目数组
        Equation[] exercises = new Equation[EQUATION_NUMBER];
        
        // 生成混合练习题
        generateExerciseOfMixedEquations(exercises, EQUATION_NUMBER);
        
        // 格式化并显示练习题
        formatAndDisplayExercise(exercises, COLUMN_NUMBER);
        
        System.out.println("====================================");
    }
    
    /**
     * 生成混合练习题（加法和减法）
     */
    public static void generateExerciseOfMixedEquations(Equation[] equationArray, int number) {
        for (int i = 0; i < number; i++) {
            Equation equation;
            do {
                // 随机生成加法或减法
                int opType = nextInt(2); // 返回0表示减法，1表示加法
                if (opType == 1) {
                    equation = generateAdditionEquation();
                } else {
                    equation = generateSubtractEquation();
                }
            } while (occursIn(equation, equationArray, i));
            
            equationArray[i] = equation;
        }
    }
    
    /**
     * 生成加法算式，确保和不超过100
     */
    public static Equation generateAdditionEquation() {
        int left, right, sum;
        do {
            left = generateOperand();
            right = generateOperand();
            sum = left + right;
        } while (sum >= 100); // 确保和不超过100
        
        return new Equation(left, right, '+');
    }
    
    /**
     * 生成减法算式，确保差不小于0
     */
    public static Equation generateSubtractEquation() {
        int left, right, difference;
        do {
            left = generateOperand();
            right = generateOperand();
            difference = left - right;
        } while (difference < 0); // 确保差不小于0
        
        return new Equation(left, right, '-');
    }
    
    /**
     * 生成0-99之间的随机整数
     */
    public static int generateOperand() {
        return random.nextInt(100);
    }
    
    /**
     * 生成0或1的随机整数
     */
    public static int nextInt(int n) {
        return random.nextInt(n);
    }
    
    /**
     * 判断两个算式是否相等
     */
    public static boolean isEqual(Equation eq1, Equation eq2) {
        // 两个算式相等当且仅当所有成员都相等
        return eq1.leftOperand == eq2.leftOperand && 
               eq1.rightOperand == eq2.rightOperand && 
               eq1.operator == eq2.operator;
    }
    
    /**
     * 检查算式是否已存在于数组中
     */
    public static boolean occursIn(Equation anEquation, Equation[] equationArray, int currentIndex) {
        // 遍历当前已填充的数组部分
        for (int i = 0; i < currentIndex; i++) {
            if (equationArray[i] != null && isEqual(anEquation, equationArray[i])) {
                return true; // 已存在
            }
        }
        return false; // 不存在
    }
    
    /**
     * 格式化并显示练习题
     */
    public static void formatAndDisplayExercise(Equation[] anExercise, int columns) {
        System.out.println("50道不重复的混合加减法练习题：");
        System.out.println("====================================");
        
        // 使用嵌套循环，外层控制行，内层控制每行的题目
        for (int row = 0; row < anExercise.length / columns + (anExercise.length % columns > 0 ? 1 : 0); row++) {
            // 计算行的起始和结束序号
            int startNum = row * columns + 1;
            int endNum = Math.min(startNum + columns - 1, anExercise.length);
            
            // 打印序号范围
            System.out.printf("%2d~%-2d: ", startNum, endNum);
            
            // 打印当前行的所有题目
            for (int col = 0; col < columns; col++) {
                int index = row * columns + col;
                if (index < anExercise.length) {
                    System.out.print(anExercise[index].toString() + "   ");
                }
            }
            System.out.println();
        }
        
        // 统计加法和减法的数量
        int additionCount = 0;
        int subtractionCount = 0;
        for (Equation eq : anExercise) {
            if (eq.operator == '+') {
                additionCount++;
            } else if (eq.operator == '-') {
                subtractionCount++;
            }
        }
        
        // 输出统计信息
        System.out.println("\n统计信息：");
        System.out.println("- 加法题目数量：" + additionCount);
        System.out.println("- 减法题目数量：" + subtractionCount);
    }
}